;Load address of IRMM is 0x7F00
;Register transfer zone is 0x7E00
;Stack used by IRMM is 0xf000 (Top)
;This enables interrupt before executing the interrupt, and disables
;before we return to the system
org 0x7F00
[bits 32]
start:
jmp init_irmm
db "Illusion RMM"
 	
 	pmstack dd 0
	
	init_irmm:
	mov [pmstack],esp
	jmp 28h:do_16		;Jump to real code seg

	[bits 16]
		do_16:
		mov ax,30h		;Real code data seg
		mov ds,ax       
		mov ss,ax
		nop
		mov ax,0xf000
		mov sp,ax
		lea bx,[do_rm]
		mov ax,0	
		push ax
		push bx
		mov eax,cr0
		and al,0xFE
		mov cr0,eax
		retf

		do_rm:
		mov ax,cs       ;Compatible real code segs
		mov ds,ax
		mov ss,ax
		nop
		mov fs,ax
		mov gs,ax
		mov ax,0
		mov es,ax
		
		
		lidt [ridtr]    ;Real mode int descriptor
                
		jmp rmm

%macro putc 1
push ax
mov ah,0x0e
mov al,%1
int 0x10
pop ax
%endmacro

;------------------------------------------------------Illusion Real mode manager:
rmm:
;Now we want interrupts to work
sti

mov ax,word[es:0x7E18]      ;Get int number
mov bl,4h       
mul bl          
mov bx,ax
mov dx,word[es:bx]          ;Real offset of int number
add bx,2        
mov ax,word[es:bx]          ;Real seg of int
pushf                       ;Set return address
push cs                    
push rfint ;(Return from int)
pushf                       ;Push int seg:offset
push ax
push dx

mov eax,dword[es:0x7E00]      ;Load all registers as passed
mov ebx,dword[es:0x7E04]
mov ecx,dword[es:0x7E08]
mov edx,dword[es:0x7E0c]
mov esi,dword[es:0x7E10]
mov edi,dword[es:0x7E14]


iret


rfint:
cli                           ;Disable interrupts
mov [0x7E00],eax
mov [0x7E04],ebx
mov [0x7E08],ecx
mov [0x7E0c],edx
mov [0x7E10],esi
mov [0x7E14],edi

pushf                         ;And flags
pop ax
mov word[es:0x7E18],ax
;-----------------------------------------------------------------End of RMM
eormm:


	mov eax,cr0                  ;Set PE bit
	or al,1
	mov cr0,eax
	jmp 08h:back2pm              ;Flush instruction prefetch cache

		[bits 32]
		back2pm:
		push eax
		mov ax,10h                   ;Data seg desc
		mov ds,ax
		mov ss,ax
		nop
		mov es,ax
		mov fs,ax
		mov gs,ax
		pop eax
		
		mov esp,[pmstack]
		
		retf                        ;Return to pm kernel


		ridtr:	dw 0xFFFF		; limit=0xFFFF
		dd 0					; base=0

times 512-($-start) db 0
